import base64
import pickle

from django.core.cache import cache
from django.shortcuts import render, redirect
from django.views.generic import View
from goods.models import GoodsType, IndexGoodsBanner, IndexPromotionBanner, IndexTypeGoodsBanner, GoodsSKU
from order.models import OrderGoods
from goods.utils import create_index_html
from django_redis import get_redis_connection
# 导入Django的分页类
from django.core.paginator import Paginator


class IndexView(View):

    def get(self, request):
        # 获取缓存数据，
        context = cache.get('context')
        if context is None:

            # 获取商品分类数据
            types = GoodsType.objects.all()
            # 获取轮播图数据
            goods_banners = IndexGoodsBanner.objects.all().order_by('index')
            # 获取促销商品数据
            promotion_banners = IndexPromotionBanner.objects.all().order_by('index')

            # 给每个分类增加商品数据 标题、图片
            for type in types:
                type.title_banners = IndexTypeGoodsBanner.objects.filter(type=type, display_type=0).order_by('index')
                type.image_banners = IndexTypeGoodsBanner.objects.filter(type=type, display_type=1).order_by('index')

            context = {
                'types': types,
                'goods_banners': goods_banners,
                'promotion_banners': promotion_banners

            }
            # 写入缓存
            cache.set('context', context, 60 * 60)

        # 获取用户数据
        user = request.user
        context['user'] = user

        # 判断用户是否登录 统计商品数量
        cart_count = 0
        user = request.user
        if user.is_authenticated():
            conn = get_redis_connection('carts')
            sku_count = conn.hgetall('sku_count_%d' % user.id)
            for key, value in sku_count.items():
                cart_count += int(value)
        else:
            cart_cookie = request.COOKIES.get('cart_cookie')
            if cart_cookie:
                # 7-2、存储过，说明cookie数据已经进行过base64的编码处理，就需要进行解码，获取存储的cookie数据
                cart_dict = pickle.loads(base64.b64decode(cart_cookie))
                for key, value in cart_dict.items():
                    cart_count += value['count']

        context['cart_count'] = cart_count

        return render(request, 'index.html', context)

        # return redirect('/static/index.html')


class GoodsDetailView(View):

    def get(self, request, pk):
        # 根据传递的sku的商品id查询对应的sku信息
        try:
            sku = GoodsSKU.objects.get(id=pk)
        except:
            return redirect('/')

        # 获取商品分类数据
        types = GoodsType.objects.all()

        # 按照销量进行查询sku数据
        new_skus = GoodsSKU.objects.all().order_by('-sales')[0:3]

        # 查询订单商品表
        sku_orders = OrderGoods.objects.filter(sku=sku)

        # 获取啊当前商品品种  sku和spu关联表  副表查询主表
        spu = sku.goods
        # 品种下的所有具体规格商品有哪些  主表查询副表
        same_spu_skus = spu.goodssku_set.exclude(id=sku.id)

        # 第二种查询：关联过滤查询  查询集数据可以调用exclude取反 count总数 order_by 排序
        same_spu_skus = GoodsSKU.objects.filter(goods_id=sku.goods_id).exclude(id=sku.id)

        # for sku_order in sku_orders:
        #     # 关联查询 订单商品查询订单基本信息
        #     sku_order.order = sku_order.order

        # 用户浏览历史记录 保存是有个前提条件 用户必须登录
        cart_count = 0
        user = request.user
        if user.is_authenticated():
            # 3-1 连接redis
            conn = get_redis_connection('history')
            # 3-2 数据需要去重。避免用户重复访问同一个商品造成数据的重复存储
            # redis的key需要是唯一的，用户是唯一的，在记录商品浏览信息时，用户是处于登录状态。request.user获取登录后的用户
            conn.lrem('history_%d' % request.user.id, 0, sku.id)
            # 写入数据
            conn.lpush('history_%d' % request.user.id, sku.id)
            # 控制浏览商品的存储数量。避免用户访问很多商品后展示浏览信息不方便，最近浏览的商品展示保留5个数据即可
            conn.ltrim('history_%d' % request.user.id, 0, 5)

            conn = get_redis_connection('carts')
            sku_count = conn.hgetall('sku_count_%d' % user.id)
            for key, value in sku_count.items():
                cart_count += int(value)
        else:
            cart_cookie = request.COOKIES.get('cart_cookie')
            if cart_cookie:
                # 7-2、存储过，说明cookie数据已经进行过base64的编码处理，就需要进行解码，获取存储的cookie数据
                cart_dict = pickle.loads(base64.b64decode(cart_cookie))
                for key, value in cart_dict.items():
                    cart_count += value['count']

        context = {'sku': sku, 'types': types, 'new_skus': new_skus, 'sku_orders': sku_orders,
                   'same_spu_skus': same_spu_skus, 'cart_count': cart_count}
        return render(request, 'detail.html', context)


class GoodsListView(View):

    def get(self, request, type_id, num_page):
        """
        type_id 分类id
        num_page 页数
        """
        # 1、获取排序字段
        sort = request.GET.get('sort', 'default')

        # 2、根据前端传递的分类id查询sku表获取对应的商品数据，按照传递的排序数据对所有的商品进行排序
        if sort == 'default':
            # 默认按照创建时间排序
            skus = GoodsSKU.objects.filter(type_id=type_id, status=1).order_by('create_time')
        elif sort == 'price':
            # 按照价格排序
            skus = GoodsSKU.objects.filter(type_id=type_id, status=1).order_by('price')
        else:
            # 按照销量排序
            skus = GoodsSKU.objects.filter(type_id=type_id, status=1).order_by('sales')
        # 3、对商品数据进行分页处理，使用Django的分页类的方法
        # 3-1 初始化分页类生成分页对象,需要传递两个参数，第一个要分页的数据，第二个分页后每页的数量
        paginator = Paginator(skus, 2)
        # 3-2 提取分页数据数据，将页数传递的进去，根据传递分页数据进行响应分页数据获取
        try:
            page_skus = paginator.page(num_page)
        except:
            return render(request, 'list.html')

        # 获取商品分类数据
        types = GoodsType.objects.all()

        # 按照销量进行查询sku数据
        new_skus = GoodsSKU.objects.all().order_by('-sales')[0:3]
        # 当前分类对象
        type = GoodsType.objects.get(id=type_id)
        context = {
            'skus_page': page_skus,
            'types': types,
            'new_skus': new_skus,
            'type': type,
            'sort': sort,
            'pages': paginator.page_range
        }

        return render(request, 'list.html', context)
